﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;
using AVEIT.autogestionAVEIT.Negocio;
using AVEIT.autogestionAVEIT.Negocio.Entidades;
using AVEIT.autogestionAVEIT.Negocio.Gestores;

namespace AVEIT.autogestionAVEIT.AccesoDatos
{
    public class ClientesDAO : AccesoADatos
    {
        static SqlConnection con;
        public ClientesDAO() { }

        static void abrirConexion() {
            con = new SqlConnection();
            try
            {
                con.ConnectionString = ConfigurationManager.ConnectionStrings["AVEIT"].ConnectionString;
                con.Open();
            }
            catch (SqlException ex)
            {
                throw new ApplicationException("Error al conectarse a la base de datos. " + ex.Message);
            }
        }

        static void cerrarConexion()
        {
            if (con != null && con.State == ConnectionState.Open)
                con.Close();
        }
        
        
        public static void grabarCliente(Cliente cliente)
        {
            SqlCommand cmd = new SqlCommand();
            SqlCommand cmd2 = new SqlCommand();
            SqlCommand cmd3 = new SqlCommand();
            SqlTransaction trans = null;
            bool graboDomicilio = false;
            
            abrirConexion();
            try
            {
                
                trans = con.BeginTransaction();
                cmd.Connection = con;
                cmd2.Connection = con;
                cmd3.Connection = con;
                cmd.Transaction = trans;
                cmd2.Transaction = trans;
                cmd3.Transaction = trans;
                
                cmd.Parameters.Add(new SqlParameter("@documento", cliente.NumeroDocumento));
                cmd.Parameters.Add(new SqlParameter("@tipo_documento", cliente.TipoDocumento));
                cmd.Parameters.Add(new SqlParameter("@Nombre", cliente.Nombre));
                cmd.Parameters.Add(new SqlParameter("@Apellido", cliente.Apellido));
                cmd.Parameters.Add(new SqlParameter("@sexo", cliente.Sexo));
                cmd.Parameters.Add(new SqlParameter("@fecha_alta", cliente.FechaAlta)); 

                cmd2.Parameters.Add(new SqlParameter("@telefono", cliente.NumeroTelefono));
                cmd2.Parameters.Add(new SqlParameter("@caracteristica", cliente.NumeroCaracteristicaTelefono));
                cmd2.Parameters.Add(new SqlParameter("@tipo_telefono", cliente.TipoTelefono));
                

                cmd3.Parameters.Add(new SqlParameter("@mail", cliente.Email));
                

                if (cliente.IdCliente.HasValue)
                {
                    cmd.CommandText = "UPDATE cliente SET documento = @documento, tipo_documento = @tipo_documento, nombre = @nombre, apellido = @apellido, sexo = @Sexo WHERE id_cliente = @Id_cliente";
                    cmd.Parameters.Add(new SqlParameter("@Id_cliente", cliente.IdCliente));
                    cmd.ExecuteNonQuery();

                    //actualizar Telefono

                    cmd2.CommandText = "UPDATE telefonoXcliente SET telefono = @telefono, caracteristica = @caracteristica, tipo_telefono = @tipo_telefono WHERE id_cliente = @Id_cliente";
                    cmd2.Parameters.Add(new SqlParameter("@Id_cliente", cliente.IdCliente));
                    cmd2.ExecuteNonQuery();

                    //actualizar Email

                    cmd3.CommandText = "UPDATE mailXcliente SET mail = @mail WHERE id_cliente = @Id_cliente";
                    cmd3.Parameters.Add(new SqlParameter("@Id_cliente", cliente.IdCliente));
                    cmd3.ExecuteNonQuery();

                    //actualizar Domicilio
                    GestorDomicilio.grabarDomicilio(cliente.domicilio);
                }
                else
                {
                    //Primero Grabar Domicilio
                    cliente.domicilio.id_domicilio = GestorDomicilio.grabarDomicilio(cliente.domicilio);
                    cmd.Parameters.Add(new SqlParameter("@id_domicilio", cliente.domicilio.id_domicilio));
                    graboDomicilio = true;
                    //grabamos el Cliente
                    cmd.CommandText = "INSERT INTO cliente(documento, tipo_documento, nombre, apellido, id_domicilio, fecha_alta, sexo) VALUES(@documento, @tipo_documento, @Nombre, @apellido, @id_domicilio, @fecha_alta, @sexo); SELECT @@identity;";
                    cliente.IdCliente = int.Parse(cmd.ExecuteScalar().ToString());

                    //grabar Telefono  
                    cmd2.CommandText = "INSERT INTO TelefonoXCliente(id_cliente, telefono, caracteristica, tipo_telefono) VALUES(@Id_cliente, @telefono, @caracteristica, @tipo_telefono)";
                    cmd2.Parameters.Add(new SqlParameter("@Id_cliente", cliente.IdCliente));
                    cmd2.ExecuteNonQuery();

                    //grabar Mail
                    cmd3.CommandText = "INSERT INTO MailXCliente(id_cliente, mail) VALUES(@Id_cliente, @mail)";
                    cmd3.Parameters.Add(new SqlParameter("@Id_cliente", cliente.IdCliente));
                    cmd3.ExecuteNonQuery();
                }

                trans.Commit();
            }
            catch (SqlException ex)
            {
                if (trans != null && graboDomicilio)
                {
                    GestorDomicilio.eliminarDomicilio(int.Parse(cliente.domicilio.id_domicilio.ToString()));
                    trans.Rollback();
                }
                throw new ApplicationException("Error al ejecutar la transaccion en la Base de Datos. " + ex.Message.ToString());
            }
            finally
            {
                cerrarConexion();
            }
        }
        
        public static void eliminarCliente(int id_cliente)
        {

            SqlCommand cmd2 = new SqlCommand();            
            SqlTransaction trans1 = null;          
            abrirConexion();
            Cliente cli=obtenerCliente(id_cliente);

            try
            {
                trans1 = con.BeginTransaction();
                cmd2.Connection = con;
                cmd2.Transaction = trans1;
               
                cmd2.CommandText = "DELETE FROM TelefonoXCliente WHERE id_cliente = @Id_cliente; " +
                    "DELETE FROM mailXcliente WHERE id_cliente = @Id_cliente; "+
                    "DELETE FROM cliente WHERE id_cliente = @Id_cliente; "+
                    "DELETE FROM Domicilio WHERE id_domicilio = @Id_domicilio";
                cmd2.Parameters.Add(new SqlParameter("@Id_cliente", cli.IdCliente));
                cmd2.Parameters.Add(new SqlParameter("@Id_domicilio", cli.domicilio.id_domicilio));
                cmd2.ExecuteNonQuery();

                trans1.Commit();
            }
            catch (Exception ex)
            {
                if (trans1 != null)
                {
                    trans1.Rollback();
                }
                throw new ApplicationException("Error al ejecutar la transaccion en la Base de Datos. " + ex.Message.ToString());
            }
            finally
            {
                cerrarConexion();
            }
        }

        public static Cliente obtenerCliente(int id_cliente)
        {
            Cliente cliente = new Cliente();
            SqlParameter pr_cli = new SqlParameter("@id_cliente", id_cliente);
            Domicilio dom = new Domicilio();
            try
            {
                string cadena = "Select c.id_cliente, c.documento, c.tipo_documento, c.nombre, c.apellido, "+
                    "c.id_domicilio, d.id_localidad, d.calle, d.numero, d.piso, d.departamento, d.barrio, d.codigoPostal,"+
                    " c.fecha_alta, c.sexo, m.mail, t.caracteristica, t.telefono, t.tipo_telefono from Cliente c "+
                    "left outer join Domicilio d on c.id_domicilio=d.id_domicilio left outer join MailXCliente m "+
                    "on c.id_cliente=m.id_cliente left outer join TelefonoXCliente t on c.id_cliente=t.id_cliente "+
                    "where c.id_cliente=@id_cliente";
                DataTable dt = consultarSQL(cadena, pr_cli);
                cliente.IdCliente = int.Parse(dt.Rows[0]["id_cliente"].ToString());
                cliente.NumeroDocumento = long.Parse(dt.Rows[0]["documento"].ToString());
                cliente.TipoDocumento = int.Parse(dt.Rows[0]["tipo_documento"].ToString());
                cliente.Nombre = dt.Rows[0]["nombre"].ToString();
                cliente.Apellido = dt.Rows[0]["apellido"].ToString();
                if (dt.Rows[0]["fecha_alta"] != DBNull.Value)
                    cliente.FechaAlta = DateTime.Parse(dt.Rows[0]["fecha_alta"].ToString());
                if (dt.Rows[0]["sexo"] != DBNull.Value)
                    cliente.Sexo = char.Parse(dt.Rows[0]["sexo"].ToString());
                if (dt.Rows[0]["mail"] != DBNull.Value)
                    cliente.Email = dt.Rows[0]["mail"].ToString();
                if (dt.Rows[0]["caracteristica"] != DBNull.Value)
                    cliente.NumeroCaracteristicaTelefono = long.Parse(dt.Rows[0]["caracteristica"].ToString());
                if (dt.Rows[0]["telefono"] != DBNull.Value)
                    cliente.NumeroTelefono = long.Parse(dt.Rows[0]["telefono"].ToString());
                if (dt.Rows[0]["tipo_telefono"] != DBNull.Value)
                    cliente.TipoTelefono = int.Parse(dt.Rows[0]["tipo_telefono"].ToString());
                if (dt.Rows[0]["id_domicilio"] != DBNull.Value)
                {
                    dom.id_domicilio = int.Parse(dt.Rows[0]["id_domicilio"].ToString());
                    dom.id_localidad = int.Parse(dt.Rows[0]["id_localidad"].ToString());
                    dom.calle = dt.Rows[0]["calle"].ToString();
                    dom.numero = int.Parse(dt.Rows[0]["numero"].ToString());
                    if (dt.Rows[0]["piso"] != DBNull.Value)
                        dom.piso = int.Parse(dt.Rows[0]["piso"].ToString());
                    if (dt.Rows[0]["departamento"] != DBNull.Value)
                        dom.departamento = dt.Rows[0]["departamento"].ToString();
                    if (dt.Rows[0]["barrio"] != DBNull.Value)
                        dom.barrio = dt.Rows[0]["barrio"].ToString();
                    if (dt.Rows[0]["codigoPostal"] != DBNull.Value)
                        dom.cod_postal = int.Parse(dt.Rows[0]["codigoPostal"].ToString());
                }
                cliente.domicilio = dom;
            }
            catch (Exception ex)
            {
                
                throw new ApplicationException(ex.Message);
            }

            return cliente;
        }

        public static List<Cliente> obtenerTodos()
        {
            List<Cliente> clientes = new List<Cliente>();
            try
            {
                string cadena = "Select c.id_cliente, c.documento as 'Nro Documento', c.tipo_documento, c.nombre as 'Nombre',"+
                    " c.apellido as 'Apellido', c.id_domicilio, d.id_localidad as 'Localidad', d.calle as 'Calle', "+
                    "d.numero as 'Nro', d.piso as 'Piso', d.departamento as 'Dpto', d.barrio as 'Barrio', d.codigoPostal as 'Codigo Postal', "+
                    "c.fecha_alta as 'Fecha de Alta', c.sexo as 'Sexo', m.mail as 'E-mail', t.caracteristica as 'Caracteristica',"+
                    " t.telefono as 'Telefono', t.tipo_telefono from Cliente c left outer join Domicilio d on c.id_domicilio=d.id_domicilio"+
                    " left outer join MailXCliente m on c.id_cliente=m.id_cliente left outer join TelefonoXCliente t on c.id_cliente=t.id_cliente";
                SqlDataReader dr = consultarSqlDReader(cadena);
                while (dr.Read())
                {
                    Cliente cliente = new Cliente();
                    Domicilio dom = new Domicilio();
                    cliente.IdCliente = (int)dr["id_cliente"];
                    cliente.NumeroDocumento = long.Parse(dr["Nro Documento"].ToString());
                    cliente.TipoDocumento = int.Parse(dr["tipo_documento"].ToString());
                    cliente.Nombre = dr["Nombre"].ToString();
                    cliente.Apellido = dr["Apellido"].ToString();
                    if (dr["Fecha de Alta"] != DBNull.Value)
                        cliente.FechaAlta = DateTime.Parse(dr["Fecha de Alta"].ToString());
                    if (dr["Sexo"] != DBNull.Value)
                        cliente.Sexo = char.Parse(dr["Sexo"].ToString());
                    if (dr["E-mail"] != DBNull.Value)
                        cliente.Email = dr["E-mail"].ToString();
                    if (dr["Telefono"] != DBNull.Value)
                        cliente.NumeroTelefono = long.Parse(dr["Telefono"].ToString());
                    if (dr["Caracteristica"] != DBNull.Value)
                        cliente.NumeroCaracteristicaTelefono = long.Parse(dr["Caracteristica"].ToString());
                    if (dr["tipo_telefono"] != DBNull.Value)
                        cliente.TipoTelefono = int.Parse(dr["tipo_telefono"].ToString());
                    if (dr["id_domicilio"] != DBNull.Value)
                    {
                        dom.id_domicilio = int.Parse(dr["id_domicilio"].ToString());
                        dom.id_localidad = int.Parse(dr["Localidad"].ToString());
                        dom.calle = dr["Calle"].ToString();
                        dom.numero = int.Parse(dr["Nro"].ToString());
                        if (dr["Piso"] != DBNull.Value)
                            dom.piso = int.Parse(dr["Piso"].ToString());
                        if (dr["Dpto"] != DBNull.Value)
                            dom.departamento = dr["Dpto"].ToString();
                        if (dr["Barrio"] != DBNull.Value)
                            dom.barrio = dr["Barrio"].ToString();
                        if (dr["Codigo Postal"] != DBNull.Value)
                            dom.cod_postal = int.Parse(dr["Codigo Postal"].ToString());
                    }
                   
                    clientes.Add(cliente);
                }
            }
            catch (Exception ex)
            {

                throw new ApplicationException(ex.Message + "Error al leer todos los clientes. ");
            }

            return clientes;

        }
        
    }
}